package com.simple.search;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


import com.simple.mapper.nrmp.QuestionAnswerMapper;
import com.simple.mapper.nrmp.QuestionMapper;
import com.simple.question.Question;
import com.simple.question.QuestionAnswer;
import com.simple.util.SpringBeanUtil;
import com.simple.vo.QuestionSortBean;

public class QuestionSearchImp {
	private static SearchUtil searchUtil = new SearchUtil(QuestionSearch.class.getResourceAsStream("question.json"));
	
	/**
	 * 查询5个已排重的数据
	 * @param text
	 * @return
	 */
	public static JSONArray searchText(String text) {
		long time = System.currentTimeMillis();
		JSONArray jsonArray = searchTextRepeat(text, 10);
		jsonArray = removeRepeat(jsonArray, 5);
		System.out.println("searchEsTime="+ (System.currentTimeMillis() - time) + "ms");
		return jsonArray;
	}
	
	/**
	 * 查询指定个数未排重的数据
	 * @param text
	 * @param size
	 * @return
	 */
	public static JSONArray searchTextRepeat(String text, int size) {
		Map<String, String> params = new HashMap<>();
		params.put("text", text);
		params.put("size", size+"");
		JSONObject response = searchUtil.execute("search_text", params);
		if(response.getIntValue("code") != 200) {
			throw new RuntimeException(response.getString("message"));
		}
		return response.getJSONObject("data").getJSONObject("hits").getJSONArray("hits");
	}
	
	/**
	 * 根据subjectId查询5个已排重数据
	 * @param text 
	 * @param subjectId 
	 * @return
	 */
	public static JSONArray searchTextSubject(String text, long subjectId) {
		long time = System.currentTimeMillis();
		JSONArray jsonArray = searchTextSubjectRepeat(text, subjectId, 10);
		jsonArray = removeRepeat(jsonArray, 5);
		System.out.println("searchEsTime="+ (System.currentTimeMillis() - time) + "ms");
		return jsonArray;
	}

	/**
	 * 根据subjectId查询指定个数未排重数据
	 * @param text
	 * @param subjectId
	 * @param size
	 * @return
	 */
	public static JSONArray searchTextSubjectRepeat(String text, long subjectId, int size) {
		Map<String, String> params = new HashMap<>();
		params.put("text", text);
		params.put("subjectId", subjectId+"");
		params.put("size", size+"");
		JSONObject response = searchUtil.execute("search_text_subject", params);
		if(response.getIntValue("code") != 200) {
			throw new RuntimeException(response.getString("message"));
		}
		return response.getJSONObject("data").getJSONObject("hits").getJSONArray("hits");
	}

	/**
	 * 根据id查找数据
	 * @param id
	 * @return
	 */
	public static JSONObject getById(long id) {
		Map<String, String> params = new HashMap<>();
		params.put("id", id+"");
		JSONObject response = searchUtil.execute("get_by_id", params);
		if(response.getIntValue("code") != 200) {
			return null;
		}
		return response.getJSONObject("data").getJSONObject("_source");
	}

	public static JSONArray searchTextMulti(List<String> supposeTexts) {
		long time = System.currentTimeMillis();
		Map<String, String> params = new HashMap<>();
		int length = supposeTexts.size();
		for(int i = 0; i < 4; i++) {
			if(i < length) {
				params.put("text"+(i+1), supposeTexts.get(i));
				System.out.println(supposeTexts.get(i));
			}
			else {
				params.put("text"+(i+1), "");
			}
		}
		params.put("size", "10");
		// params.put("text6", "");
		// System.out.println(fullText);
		JSONObject response = searchUtil.execute("search_text_multi", params);
		if(response.getIntValue("code") != 200) {
			throw new RuntimeException(response.getString("message"));
		}
		JSONArray jsonArray = response.getJSONObject("data").getJSONObject("hits").getJSONArray("hits");
		jsonArray = removeRepeat(jsonArray, 5);
		System.out.println("searchEsPointTime="+ (System.currentTimeMillis() - time) + "ms");
		return jsonArray;
	}
	
	
	/**
	 * 删除重复数据，并且根据知识点排序，而且过滤掉不要的数据
	 * @param jsonArray
	 * @param remainSize 要返回的最大条数
	 * @return
	 */
	private static JSONArray removeRepeat(JSONArray jsonArray, int remainSize) {
		if(jsonArray.size() == 0) {
			return jsonArray;
		}
		JSONArray returnArray = new JSONArray();
		List<Long> ids = new ArrayList<>(jsonArray.size());
		for(int i = 0; i < jsonArray.size() && returnArray.size() < remainSize; i++) {
			JSONObject indexObject = jsonArray.getJSONObject(i).getJSONObject("_source");
			long id = indexObject.getLong("id");
			ids.add(id);
		}
		
		List<Question> questionList = SpringBeanUtil.getBean(QuestionMapper.class).selectByIdList(ids);
		List<QuestionAnswer> questionAnswerList = SpringBeanUtil.getBean(QuestionAnswerMapper.class).selectByQuestionIds(new HashSet<Long>(ids));
		Map<Long, QuestionAnswer> answerMap = new HashMap<>();
		for(QuestionAnswer questionAnswer: questionAnswerList) {
			answerMap.put(questionAnswer.getQuestionId(), questionAnswer);
		}
		Set<Long> questionSet = new HashSet<>(); //存放数据库里面的题目id
		Set<Long> kpointSet = new HashSet<>(); //存放有知识点的题目id
		Set<Long> answerSet = new HashSet<>(); //存放有答案的题目id
		Set<Long> analysSet = new HashSet<>(); //存放有解析的题目id
		Set<Long> summarySet = new HashSet<>(); //存放有归纳总结的题目id
		for(Question question: questionList) {
			// 教师答疑题不要出现
			if(question.getResourceTypeId() != 10 && question.getStatus() == 3) {
				long id = question.getId();
				questionSet.add(id);
				if(question.getKPointId() > 0) {
					kpointSet.add(id);
				}
				QuestionAnswer answer = answerMap.get(id);
				if(answer != null) {
					if(answer.getAnswer() != null && answer.getAnswer().trim().length() > 0) {
						answerSet.add(id);
					}
					if(answer.getShowAnswer() != null && answer.getShowAnswer().trim().length() > 0) {
						answerSet.add(id);
					}
					if(answer.getAnalysis() != null && answer.getAnalysis().trim().length() > 0) {
						analysSet.add(id);
					}
					if(answer.getSummary() != null && answer.getSummary().trim().length() > 0) {
						summarySet.add(id);
					}
				}
			}
		}
		Map<String, List<QuestionSortBean>> questionMap = new LinkedHashMap<>();
		for(int i = 0; i < jsonArray.size() && questionMap.size() < remainSize; i++) {
			JSONObject indexObject = jsonArray.getJSONObject(i).getJSONObject("_source");
			long id = indexObject.getLong("id");
			if(!questionSet.contains(id)) {
				continue;
			}
			String md5 = indexObject.getString("md5");
			QuestionSortBean sortBean = new QuestionSortBean();
			sortBean.setId(id);
			sortBean.setJsonObject(jsonArray.getJSONObject(i));
			List<QuestionSortBean> sortBeanList = questionMap.get(md5);
			if(sortBeanList == null) {
				sortBeanList = new ArrayList<>();
				questionMap.put(md5, sortBeanList);
			}
			sortBeanList.add(sortBean);
		}
		for(String key: questionMap.keySet()) {
			List<QuestionSortBean> sortBeanList = questionMap.get(key);
			for(int i = 0; i < sortBeanList.size(); i++) {
				QuestionSortBean sortBean = sortBeanList.get(i);
				long id = sortBean.getId();
				/*
				 分数相同，属性来判断，按照以下四种，优先级从上往下；
				①属性含知识点、答案、解析、归纳总结；
				②属性含知识点、答案、解析；
				③属性取含知识点、答案；
				④属性含答案、解析、归纳总结；
				⑤属性含答案、解析；
				⑥属性只有答案；
				 */
				if(kpointSet.contains(id) && answerSet.contains(id) && analysSet.contains(id) && summarySet.contains(id)) {
					sortBean.setScore(6);
				}
				else if(kpointSet.contains(id) && answerSet.contains(id) && analysSet.contains(id)) {
					sortBean.setScore(5);
				}
				else if(kpointSet.contains(id) && answerSet.contains(id)) {
					sortBean.setScore(4);
				}
				else if(answerSet.contains(id) && analysSet.contains(id) && summarySet.contains(id)) {
					sortBean.setScore(3);
				}	
				else if(answerSet.contains(id) && analysSet.contains(id)) {
					sortBean.setScore(2);
				}
				else if(answerSet.contains(id)){
					sortBean.setScore(1);
				}
			}
			Collections.sort(sortBeanList, new Comparator<QuestionSortBean>() {

				@Override
				public int compare(QuestionSortBean o1, QuestionSortBean o2) {
					return o2.getScore() - o1.getScore();
				}
			});
			returnArray.add(sortBeanList.get(0).getJsonObject());
		}
		return returnArray;
	}
}
